#include "widget.h"
#include "ui_widget.h"
#include<QMessageBox>
#include <QProgressBar>
#include <QMap>
#include <QTimer>
#include<Qthread>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    qWarning() << "Test";
    // 初始化Redis连接
    if (!RedisManager::instance().connect()) {
        QMessageBox::warning(this, "Redis连接", "无法连接到Redis服务器");
    }
    else {
        // 连接成功
        qDebug() << "Redis connected successfully";
    }

    m_pKernel=new tcpkernel;//new tcpkernel这个对象创建完之后，m_pKernel才会被赋值为 tcpkernel 对象的地址
    ui->progressBar->setValue(0);

    if(!m_pKernel->open()){
        QMessageBox::information(this,"connect server","err");
    }
    m_pLogin.setKernel(m_pKernel);
    m_pLogin.show();

    connect((tcpkernel*)m_pKernel,&tcpkernel::signal_register,&m_pLogin,&login::slots_register,Qt::BlockingQueuedConnection);
    connect((tcpkernel*)m_pKernel,&tcpkernel::signal_login,this,&Widget::slots_login,Qt::BlockingQueuedConnection);
    connect((tcpkernel*)m_pKernel,&tcpkernel::signal_getfilelist,this,&Widget::slots_getfilelist,Qt::BlockingQueuedConnection);
    connect((tcpkernel*)m_pKernel,&tcpkernel::signal_uploadfile,this,&Widget::slots_uploadfile,Qt::BlockingQueuedConnection);
    connect((tcpkernel*)m_pKernel,&tcpkernel::signal_downloadfileinfo,this, &Widget::slots_downloadfileinfo, Qt::BlockingQueuedConnection);
    connect((tcpkernel*)m_pKernel,&tcpkernel::signal_downloadfileblock,this, &Widget::slots_downloadfileblock, Qt::BlockingQueuedConnection);
    // 初始化进度动画定时器
    connect(&m_progressAnimationTimer, &QTimer::timeout, this, &Widget::updateProgressAnimation);
    m_progressAnimationTimer.start(100); // 每50毫秒更新一次动画
    connect((tcpkernel*)m_pKernel, &tcpkernel::signal_deletefile,
            this, &Widget::slots_deletefile, Qt::BlockingQueuedConnection);

    connect((tcpkernel*)m_pKernel, &tcpkernel::signal_searchfile,
            this, &Widget::slots_searchfile, Qt::BlockingQueuedConnection); 
    connect((tcpkernel*)m_pKernel, &tcpkernel::signal_rename,
            this, &Widget::slots_rename, Qt::BlockingQueuedConnection);
    m_bIsSearchMode = false;
    m_currentSearchKey = "";
    m_currentSearchType = SEARCH_BY_PARTIAL;
    connect(&m_uploadSaveTimer, &QTimer::timeout, this, &Widget::saveUploadTasks);
    m_uploadSaveTimer.start(5000);
    // 加载未完成的上传任务
    loadUploadTasks();
}
Widget::~Widget()
{
    saveUploadTasks(); // 退出前保存一次
    delete ui;
    delete m_pKernel;
}
void Widget::slots_login(STRU_LOGIN_RS *pslr)
{
    const char* pszResult=NULL;
    if(pslr->m_szResult==loginusernoexist){
        pszResult="loginusernoexist";
    }
    else if(pslr->m_szResult==loginpassword_err){
        pszResult="loginpassword_err";
    }
    else{
        m_userId=pslr->m_userId;
        m_pLogin.hide();
        this->show();
        m_currentPage = 0;
        //获取文件列表请求包
        STRU_GETFILELIST_RQ sgr;
        sgr.m_userId=m_userId;
        sgr.m_pageIndex = m_currentPage;
        sgr.m_pageSize = 15;  // 每页15个文件
        m_pKernel->sendData((char*)&sgr,sizeof(sgr));
        return;
    }
    QMessageBox::information(this,"tip",pszResult);
}

void Widget::slots_getfilelist(STRU_GETFILELIST_RS *psgr)
{
    // 保存分页信息
    m_totalFiles = psgr->m_totalCount;
    m_totalPages = (m_totalFiles + psgr->m_pageSize - 1) / psgr->m_pageSize;

    // 更新分页控件显示
    ui->label->setText(
        QString("第 %1 页/共 %2 页 (共 %3 个文件)")
            .arg(m_currentPage + 1)
            .arg(m_totalPages)
            .arg(m_totalFiles)
        );

    // 清空表格
    ui->tableWidget->setColumnWidth(0, 400);
    ui->tableWidget->setColumnWidth(2, 400);
    ui->tableWidget->setRowCount(0);
    if (m_bIsSearchMode) return; 
    ui->tableWidget->setRowCount(psgr->m_nFileNum);

    for(int i=0;i<psgr->m_nFileNum;i++){
        //文件名
        QTableWidgetItem*pItem=new QTableWidgetItem(QIcon(":/2.jpg"),psgr->m_aryFileInfo[i].m_szFileName);
        ui->tableWidget->setItem(i,0,pItem);
        //文件大小
        QString str=QString::number(psgr->m_aryFileInfo[i].m_filesize);
        pItem=new QTableWidgetItem(str);
        ui->tableWidget->setItem(i,1,pItem);
        //文件上传时间
        pItem=new QTableWidgetItem(psgr->m_aryFileInfo[i].m_szFileUploadTime);
        ui->tableWidget->setItem(i,2,pItem);
        // 添加进度条控件（已上传文件显示100%）
        QProgressBar *progressBar = new QProgressBar();
        progressBar->setRange(0, 100);
        progressBar->setValue(100); // 已上传文件显示完成
        progressBar->setTextVisible(true);
        progressBar->setFormat("已完成 %p%");
        ui->tableWidget->setCellWidget(i, 3, progressBar);
    }
}

void Widget::slots_uploadfile(STRU_UPLOADFILEINFO_RS *psur)
{
    STRU_FILE *pfile = nullptr;
    auto ite = m_lstFileInfo.begin();
    while(ite != m_lstFileInfo.end()) {
        if(0 == strcmp(psur->m_szFileName, (*ite)->m_szFileName) &&
            0 == strcmp(psur->m_szFileMD5, (*ite)->m_szFileMD5)) {
            pfile = *ite;
            break;
        }
        ite++;
    }
    if(!pfile) return;
    // 更新进度条标题
    QString title = QString("%1 - 上传进度").arg(pfile->m_szFileName);
    pfile->m_pProgressBar->setFormat(title + " %p%");
    // 文件已上传过
    if(psur->m_szResult == uploadfileinfo_isuploaded) {
        pfile->m_pProgressBar->setValue(100);
        QMessageBox::information(this, "文件上传", "文件已存在服务器，无需重复上传");
        RedisManager::instance().removeUploadTask(m_userId, pfile->m_szFileMD5);
        m_lstFileInfo.remove(pfile);
        delete pfile;
        return;
    }
    // 秒传
    if(psur->m_szResult == uploadfileinfo_flash) {
        pfile->m_pProgressBar->setValue(100);
        QMessageBox::information(this, "文件上传", "文件秒传成功！");
        RedisManager::instance().removeUploadTask(m_userId, pfile->m_szFileMD5);
        m_lstFileInfo.remove(pfile);
        delete pfile;
        return;
    }
    // 断点续传或正常上传
    FILE* p = fopen(pfile->m_szFilePath, "rb");
    if(!p) {
        QMessageBox::warning(this, "错误", "无法打开文件");
        return;
    }
    // 设置文件指针位置
    fseek(p, pfile->m_pos, SEEK_SET);
    // 更新Redis任务状态为上传中
    RedisManager::instance().resumeUploadTask(m_userId, pfile->m_szFileMD5);
    // 读文件内容并发送（添加暂停检查）
    bool bPaused = false;
    while(true) {
        // 检查Redis中的暂停状态（每发送一个块检查一次）
        std::map<std::string, std::string> taskInfo;
        if(RedisManager::instance().getUploadTask(m_userId, pfile->m_szFileMD5, taskInfo)) {
            if(taskInfo["status"] == "paused") {
                qDebug() << "上传任务已暂停，停止上传";
                bPaused = true;
                break;
            }
        }
        STRU_UPLOADFILEBLOCK_RQ sur;
        sur.m_fileId = psur->m_fileId;
        sur.m_userId = m_userId;
        size_t readnum = fread(sur.m_szFileContent, sizeof(char), sizeof(sur.m_szFileContent), p);
        if(readnum > 0) {
            sur.m_fileblocksize = readnum;
            if(!m_pKernel->sendData((char*)&sur, sizeof(sur))) {
                QMessageBox::warning(this, "错误", "网络发送失败");
                break;
            }
            QThread::msleep(1); // 10毫秒延迟（可根据网络状况调整）
            pfile->m_pos += readnum;
            RedisManager::instance().updateUploadProgress(m_userId, pfile->m_szFileMD5, pfile->m_pos);
            int progress = static_cast<int>((pfile->m_pos * 100) / pfile->m_FileSize);
            pfile->m_pProgressBar->setValue(progress);
            QCoreApplication::processEvents();
        } else {
            break;
        }
    }


    fclose(p);
    if(bPaused) {
        // 暂停状态，不删除任务，保留进度
        pfile->m_pProgressBar->setStyleSheet("QProgressBar::chunk { background-color: orange; }");
        pfile->m_pProgressBar->setFormat(QString("%1 - 已暂停 %p%").arg(pfile->m_szFileName));
        return;
    } // 上传完成处理
    if(pfile->m_pos == pfile->m_FileSize) {
        pfile->m_pProgressBar->setValue(100);
        QMessageBox::information(this, "上传完成", "文件上传成功！");
        RedisManager::instance().removeUploadTask(m_userId, pfile->m_szFileMD5);
        m_lstFileInfo.remove(pfile);
        delete pfile;
        // 刷新文件列表
        STRU_GETFILELIST_RQ sgr;
        sgr.m_userId = m_userId;
        sgr.m_pageIndex = 0;
        sgr.m_pageSize = 15;
        m_pKernel->sendData((char*)&sgr, sizeof(sgr));
    }   }
void Widget::slots_downloadfileinfo(STRU_DOWNLOADFILEINFO_RS *psdr)
{ if (psdr->m_nResult == downloadfileinfo_file_not_exist) {
        QMessageBox::information(this, "Download", "File not exist.");
        return;
    } // 弹出保存文件对话框- 用户选择保存位置
    QString savePath = QFileDialog::getSaveFileName(this, tr("Save File"),
                                                    psdr->m_szFileName,
                                                    tr("All Files (*)"));
    if (savePath.isEmpty()) {
        return;
    }
    // 创建文件并准备写入
    QFile *file = new QFile(savePath);
    if (!file->open(QIODevice::WriteOnly)) {
        QMessageBox::warning(this, "Download", "Cannot open file for writing.");
        delete file;
        return;
    }
    //进度条
    m_targetProgress = 0.0;
    m_currentDisplayProgress = 0.0;
    ui->progressBar->setValue(0);
    // 记录下载文件信息
    DownloadFileInfo *pInfo = new DownloadFileInfo;
    pInfo->file = file;
    pInfo->fileId = psdr->m_fileId;
    pInfo->fileSize = psdr->m_filesize;
    pInfo->receivedSize = 0;
    strcpy(pInfo->szMD5, psdr->m_szFileMD5);
    m_mapDownloadFile.insert(psdr->m_fileId, pInfo);
    // 开始请求第一个块
    requestNextBlock(psdr->m_fileId);
}


string FileDigest(QString filename) {
    QFile file(filename);
    file.open(QIODevice::ReadOnly);
    if (!file.isOpen())
        return "";
    MD5 md5;
    char buffer[1024];
    while (1)
    {
        qint64 length =  file.read(buffer, 1024);

        if (length > 0)
            md5.update(buffer, length);
        else
            break;
    }
    file.close();
    return md5.toString();
}
void Widget::slots_downloadfileblock(STRU_DOWNLOADFILEBLOCK_RS *psdr)
{
    if (!m_mapDownloadFile.contains(psdr->m_fileId)) return;
    DownloadFileInfo *pInfo = m_mapDownloadFile.value(psdr->m_fileId);
    // 写入文件
    if (psdr->m_blockSize > 0) {
        pInfo->file->write(psdr->m_szFileContent, psdr->m_blockSize);
        pInfo->receivedSize += psdr->m_blockSize;
    }
    int actualProgress = (pInfo->receivedSize * 100) / pInfo->fileSize;
    // 更新目标进度（动画会平滑过渡到这个值）
    m_targetProgress = actualProgress;

    int progress = (pInfo->receivedSize * 100) / pInfo->fileSize;
    ui->progressBar->setValue(progress);
   // 检查是否下载完成
    if (pInfo->receivedSize < pInfo->fileSize) {
        // 请求下一个块
        requestNextBlock(psdr->m_fileId);
    } else {
        // 下载完成，强制显示100%
        m_targetProgress = 100.0;
        m_currentDisplayProgress = 100.0;
        ui->progressBar->setValue(100);
        // 下载完成
        pInfo->file->close();
        // 校验MD5
        QString filePath = pInfo->file->fileName();
        string actualMD5 = FileDigest(filePath);

        if (strcmp(actualMD5.c_str(), pInfo->szMD5) == 0) {
            QMessageBox::information(this, "Download", "下载完成且MD5验证通过");
        } else {
            QMessageBox::warning(this, "Download", "下载完成但MD5不匹配!");
        }
        // 清理资源
        delete pInfo->file;
        delete pInfo;
        m_mapDownloadFile.remove(psdr->m_fileId);
        ui->progressBar->setValue(0);
    }
}

void Widget::slots_deletefile(STRU_DELETEFILE_RS *psdr)
{
    if (psdr->m_nResult == deletefile_success) {
        //文件总数-1
        m_totalFiles--;
        // 从表格中移除选中的行
        int row = ui->tableWidget->currentRow();
        if (row >= 0) {
            ui->tableWidget->removeRow(row);
        }
        if (m_bIsSearchMode) {
            // 在搜索模式下，重新执行搜索
            on_pushButton_5_clicked(); // 调用搜索按钮的点击事件
        } else {
            // 在普通模式下，刷新普通文件列表
            STRU_GETFILELIST_RQ sgr;
            sgr.m_userId = m_userId;
            sgr.m_pageIndex =0;
            sgr.m_pageSize = 15;  // 每页15个文件
            m_pKernel->sendData((char*)&sgr, sizeof(sgr));
        }
        QMessageBox::information(this, "删除文件", "文件删除成功");
    }
    else if (psdr->m_nResult == deletefile_not_exist) {
        QMessageBox::warning(this, "删除文件", "文件不存在");
    }
    else {
        QMessageBox::warning(this, "删除文件", "文件删除失败");
    }
}


void Widget::slots_searchfile(STRU_SEARCHFILE_RS *psr)
{
    // 清空表格
    ui->tableWidget->setRowCount(0);
    // 显示搜索结果
    ui->tableWidget->setRowCount(psr->m_nFileNum);
    for (int i = 0; i < psr->m_nFileNum; i++) {
        // 文件名
        QTableWidgetItem* pItem = new QTableWidgetItem(QIcon(":/2.jpg"), psr->m_aryFileInfo[i].m_szFileName);
        ui->tableWidget->setItem(i, 0, pItem);

        // 文件大小
        QString str = QString::number(psr->m_aryFileInfo[i].m_filesize);
        pItem = new QTableWidgetItem(str);
        ui->tableWidget->setItem(i, 1, pItem);

        // 文件上传时间
        pItem = new QTableWidgetItem(psr->m_aryFileInfo[i].m_szFileUploadTime);
        ui->tableWidget->setItem(i, 2, pItem);

        // 进度条（已上传文件显示100%）
        QProgressBar* progressBar = new QProgressBar();
        progressBar->setRange(0, 100);
        progressBar->setValue(100);
        progressBar->setTextVisible(true);
        progressBar->setFormat("已完成 %p%");
        ui->tableWidget->setCellWidget(i, 3, progressBar);
    }
    // 更新状态栏显示
    QString status = QString("找到 %1 个文件").arg(psr->m_totalCount);
    if (psr->m_nFileNum < psr->m_totalCount) {
        status += QString("（显示前 %1 个）").arg(psr->m_nFileNum);
    }
}
void Widget::slots_rename(STRU_RENAME_RS *prs)
{
    if (prs->m_nResult == 1) {
        QMessageBox::information(this, "重命名", "文件重命名成功");
        // 刷新文件列表
        STRU_GETFILELIST_RQ sgr;
        sgr.m_userId = m_userId;
        sgr.m_pageIndex = m_currentPage; // 保持当前页码
        sgr.m_pageSize = 15; // 保持当前页大小
        m_pKernel->sendData((char*)&sgr, sizeof(sgr));
    }
    else if (prs->m_nResult == 2) {
        QMessageBox::warning(this, "重命名", "文件不存在"); }
    else if (prs->m_nResult == 3) {
        QMessageBox::warning(this, "重命名", "新文件名已存在"); }
    else {
        QMessageBox::warning(this, "重命名", "重命名失败");}
}




void Widget::on_pushButton_clicked()
{   QString filepath = QFileDialog::getOpenFileName(this,
                                                    tr("Open File"), ".", "ALL files (*.*);;Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)");

    if(filepath.isEmpty()) return;

    QString fileName = filepath.section('/', -1);
    QFile file(filepath);
    if(!file.open(QIODevice::ReadOnly)) {
        QMessageBox::warning(this, "错误", "无法打开文件");
        return;
    }
    qint64 filesize = file.size();
    file.close();

    string strMd5 = FileDigest(filepath);
    QDateTime date = QDateTime::currentDateTime();
    QString strDate = date.toString("yyyy-MM-dd hh:mm:ss");

    // 检查Redis中是否已有该任务
    std::map<std::string, std::string> taskInfo;
    bool taskExists = RedisManager::instance().getUploadTask(m_userId, strMd5, taskInfo);
    if(taskExists) {
        // 已有任务，询问用户是否继续
        QString status = QString::fromStdString(taskInfo["status"]);
        long long uploadedSize = std::stoll(taskInfo["uploaded_size"]);
        long long totalSize = std::stoll(taskInfo["file_size"]);

        int progress = static_cast<int>((uploadedSize * 100) / totalSize);

        QMessageBox::StandardButton reply;
        if(status == "paused") {
            reply = QMessageBox::question(this, "发现未完成的上传任务",
                                          QString("发现一个未完成的上传任务 '%1' (已上传 %2%)。是否继续上传?")
                                              .arg(QString::fromStdString(taskInfo["file_name"]))
                                              .arg(progress),
                                          QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
        } else {
            reply = QMessageBox::question(this, "发现上传任务",
                                          QString("发现一个上传任务 '%1' (已上传 %2%)。是否继续上传?")
                                              .arg(QString::fromStdString(taskInfo["file_name"]))
                                              .arg(progress),
                                          QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
        }

        if(reply == QMessageBox::Cancel) return;

        if(reply == QMessageBox::No) {
            // 删除现有任务，重新开始
            RedisManager::instance().removeUploadTask(m_userId, strMd5);
            taskExists = false;
        }
    }

    // 创建新任务或继续现有任务
    STRU_FILE* pfile = new STRU_FILE;
    strcpy(pfile->m_szFileName, fileName.toStdString().c_str());
    strcpy(pfile->m_szFileMD5, strMd5.c_str());
    strcpy(pfile->m_szFilePath, filepath.toStdString().c_str());
    strcpy(pfile->m_szFileuploadTime, strDate.toStdString().c_str());
    pfile->m_FileSize = filesize;

    if(taskExists) {
        pfile->m_pos = std::stoll(taskInfo["uploaded_size"]);
    } else {
        pfile->m_pos = 0;
        // 在Redis中创建新任务
        RedisManager::instance().createUploadTask(m_userId, strMd5,
                                                  fileName.toStdString(), filesize, filepath.toStdString());
    }

    // 在表格中添加一行
    int row = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(row);

    // 添加文件名
    QTableWidgetItem* pItem = new QTableWidgetItem(QIcon(":/2.jpg"), fileName);
    ui->tableWidget->setItem(row, 0, pItem);

    // 添加文件大小
    QString sizeStr = QString::number(filesize);
    pItem = new QTableWidgetItem(sizeStr);
    ui->tableWidget->setItem(row, 1, pItem);

    // 添加上传时间
    pItem = new QTableWidgetItem(strDate);
    ui->tableWidget->setItem(row, 2, pItem);

    // 创建并添加进度条
    QProgressBar* progressBar = new QProgressBar();
    progressBar->setRange(0, 100);
    progressBar->setValue(static_cast<int>((pfile->m_pos * 100) / pfile->m_FileSize));
    progressBar->setTextVisible(true);
    progressBar->setFormat("已上传 %p%");
    ui->tableWidget->setCellWidget(row, 3, progressBar);

    // 保存进度条指针到文件结构
    pfile->m_pProgressBar = progressBar;
    pfile->m_rowIndex = row;

    // 添加到文件列表
    m_lstFileInfo.push_back(pfile);

    // 发送上传请求
    STRU_UPLOADFILEINFO_RQ sur;
    sur.m_filesize = filesize;
    strcpy(sur.m_szFileMD5, strMd5.c_str());
    strcpy(sur.m_szFileName, fileName.toStdString().c_str());
    strcpy(sur.m_szFileUploadTime, strDate.toStdString().c_str());
    sur.m_userId = m_userId;
    sur.m_filepos = pfile->m_pos; // 发送当前上传位置
    m_pKernel->sendData((char*)&sur, sizeof(sur));


}

void Widget::on_pushButton_2_clicked()
{
    int row = ui->tableWidget->currentRow();
    if (row < 0) {
        QMessageBox::warning(this, "Download", "请选择要下载的文件");
        return;
    }

    QTableWidgetItem *item = ui->tableWidget->item(row, 0);
    QString fileName = item->text();

    STRU_DOWNLOADFILEINFO_RQ sdr;
    sdr.m_userId = m_userId;
    strcpy(sdr.m_szFileName, fileName.toStdString().c_str());
    m_pKernel->sendData((char*)&sdr, sizeof(sdr));
}


void Widget::updateProgressAnimation()
{
    // 如果当前显示进度已达到目标进度，则无需更新
    if (qFuzzyCompare(m_currentDisplayProgress, m_targetProgress)) {
        return;
    }
    // 平滑过渡到目标进度
    double step = (m_targetProgress - m_currentDisplayProgress) * 0.2;
    m_currentDisplayProgress += step;
    // 如果接近目标值，直接设置
    if (qAbs(m_targetProgress - m_currentDisplayProgress) < 0.5) {
        m_currentDisplayProgress = m_targetProgress;
    }

    // 更新UI进度条
    ui->progressBar->setValue(static_cast<int>(m_currentDisplayProgress));

    // 处理UI事件，确保更新可见
    QCoreApplication::processEvents();
}

void Widget::requestNextBlock(long long fileId)
{
    if (!m_mapDownloadFile.contains(fileId)) return;

    DownloadFileInfo *pInfo = m_mapDownloadFile.value(fileId);

    STRU_DOWNLOADFILEBLOCK_RQ sdr;
    sdr.m_fileId = fileId;
    sdr.m_pos = pInfo->receivedSize;

    m_pKernel->sendData((char*)&sdr, sizeof(sdr));
}

void Widget::saveUploadTasks()
{
    QSettings settings("MyCompany", "FileTransferApp");
    settings.beginWriteArray("uploadTasks");

    int i = 0;
    for (auto it = m_uploadTasks.begin(); it != m_uploadTasks.end(); ++it) {
        STRU_FILE* task = it.value();
        settings.setArrayIndex(i++);

        settings.setValue("filePath", task->m_szFilePath);
        settings.setValue("fileName", task->m_szFileName);
        settings.setValue("uploadTime", task->m_szFileuploadTime);
        settings.setValue("fileMD5", task->m_szFileMD5);
        settings.setValue("fileSize", static_cast<qint64>(task->m_FileSize));
        settings.setValue("position", static_cast<qint64>(task->m_pos));
        settings.setValue("fileId", static_cast<qint64>(task->m_fileId));
        settings.setValue("status", task->m_status);
        settings.setValue("rowIndex", task->m_rowIndex);
    }

    settings.endArray();
}

void Widget::loadUploadTasks()
{
    auto tasks = RedisManager::instance().getUserUploadTasks(m_userId);

    for (const auto& taskInfo : tasks) {
        try {
            STRU_FILE* pfile = new STRU_FILE;

            // 从Redis任务信息填充结构体
            strcpy(pfile->m_szFileName, taskInfo.at("file_name").c_str());
            strcpy(pfile->m_szFileMD5, taskInfo.at("file_md5").c_str());
            strcpy(pfile->m_szFilePath, taskInfo.at("file_path").c_str());
            pfile->m_FileSize = std::stoll(taskInfo.at("file_size"));
            pfile->m_pos = std::stoll(taskInfo.at("uploaded_size"));

            QString status = QString::fromStdString(taskInfo.at("status"));

            // 在表格中添加一行
            int row = ui->tableWidget->rowCount();
            ui->tableWidget->insertRow(row);

            // 添加文件名
            QTableWidgetItem* pItem = new QTableWidgetItem(QIcon(":/2.jpg"), pfile->m_szFileName);
            ui->tableWidget->setItem(row, 0, pItem);

            // 添加文件大小
            QString sizeStr = QString::number(pfile->m_FileSize);
            pItem = new QTableWidgetItem(sizeStr);
            ui->tableWidget->setItem(row, 1, pItem);

            // 添加上传时间 (可以从Redis添加或使用当前时间)
            pItem = new QTableWidgetItem(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
            ui->tableWidget->setItem(row, 2, pItem);

            // 创建进度条
            QProgressBar* progressBar = new QProgressBar();
            progressBar->setRange(0, 100);
            int progress = (pfile->m_pos * 100) / pfile->m_FileSize;
            progressBar->setValue(progress);
            progressBar->setTextVisible(true);

            // 根据状态设置不同样式
            if (status == "paused") {
                progressBar->setStyleSheet("QProgressBar::chunk { background-color: orange; }");
                progressBar->setFormat(QString("%1 - 已暂停 %p%").arg(pfile->m_szFileName));
            } else {
                progressBar->setStyleSheet("QProgressBar::chunk { background-color: #41b6c4; }");
                progressBar->setFormat(QString("%1 - 上传中 %p%").arg(pfile->m_szFileName));
            }

            ui->tableWidget->setCellWidget(row, 3, progressBar);
            pfile->m_pProgressBar = progressBar;
            pfile->m_rowIndex = row;

            m_lstFileInfo.push_back(pfile);
        } catch (const std::exception& e) {
            qDebug() << "加载上传任务出错:" << e.what();
        }
    }
}

void Widget::removeUploadTask(const QString &filePath)
{
    if (m_uploadTasks.contains(filePath)) {
        m_uploadTasks.remove(filePath);
        saveUploadTasks();
    }
}

void Widget::on_pushButton_6_clicked()
{
    int row = ui->tableWidget->currentRow();
    if (row < 0) {
        QMessageBox::warning(this, "删除文件", "请先选择一个文件");
        return;
    }
//文件名字的获取
    QTableWidgetItem *item = ui->tableWidget->item(row, 0);
    QString fileName = item->text();

    // 发送删除请求
    STRU_DELETEFILE_RQ sdr;
    sdr.m_userId = m_userId;
    strcpy(sdr.m_szFileName, fileName.toStdString().c_str());

    m_pKernel->sendData((char*)&sdr, sizeof(sdr));
}

void Widget::on_pushButton_5_clicked()
{
    QString searchText = ui->lineEdit_2->text().trimmed();
    // 判断搜索类型（文件名/日期）
    QRegularExpression dateRegex("\\d{4}-\\d{2}-\\d{2}");
    if (dateRegex.match(searchText).hasMatch()) {
        // 日期搜索
        m_currentSearchType = SEARCH_BY_TIME;
    } else {
        // 文件名搜索
        m_currentSearchType = SEARCH_BY_PARTIAL;
    }

    m_currentSearchKey = searchText;
    m_bIsSearchMode = true;

    // 发送搜索请求
    STRU_SEARCHFILE_RQ ssr;
    ssr.m_userId = m_userId;
    ssr.m_searchType = m_currentSearchType;
    strcpy(ssr.m_searchKey, searchText.toStdString().c_str());

    // 如果是日期搜索，设置日期范围
    if (m_currentSearchType == SEARCH_BY_TIME) {
        QDate searchDate = QDate::fromString(searchText, "yyyy-MM-dd");
        strcpy(ssr.m_startTime, searchDate.toString("yyyy-MM-dd 00:00:00").toStdString().c_str());
        strcpy(ssr.m_endTime, searchDate.toString("yyyy-MM-dd 23:59:59").toStdString().c_str());
    }
    ssr.m_pageIndex = 0; // 第一页
    ssr.m_pageSize = FILENUM; // 每页数量
    m_pKernel->sendData((char*)&ssr, sizeof(ssr));
}

void Widget::on_pushButton_3_clicked()
{

    m_bIsSearchMode = false;
    ui->lineEdit_2->clear();

    // 重新请求整个文件列表
    STRU_GETFILELIST_RQ sgr;
    sgr.m_userId = m_userId;
    sgr.m_pageIndex = 0;
    sgr.m_pageSize = 15;  // 每页15个文件
    m_pKernel->sendData((char*)&sgr, sizeof(sgr));
}


void Widget::on_pushButton_4_clicked()
{
    // 获取当前选中的行号
    int row = ui->tableWidget->currentRow();
    // 如果没有选中任何行（row < 0），则弹出警告提示用户选择文件
    if (row < 0) {
        QMessageBox::warning(this, "重命名", "请先选择一个文件");
        return;
    }
     // 获取选中行的第一个单元格（列0）的文件名
    QTableWidgetItem *item = ui->tableWidget->item(row, 0);
    QString oldFileName = item->text();

    // 弹出输入框获取新文件名
    // 如果用户取消输入、新文件名为空或新文件名与旧文件名相同，则直接返回
    bool ok;
    QString newFileName = QInputDialog::getText(this, "重命名", "请输入新的文件名：",
                                                QLineEdit::Normal, oldFileName, &ok);
    if (!ok || newFileName.isEmpty() || newFileName == oldFileName) {
        return;
    }

    // 发送重命名请求
    STRU_RENAME_RQ rq;
    rq.m_userId = m_userId;
    // 设置旧文件名和新文件名
    strcpy(rq.m_szOldFileName, oldFileName.toStdString().c_str());
    strcpy(rq.m_szNewFileName, newFileName.toStdString().c_str());
    // 通过内核发送重命名请求给服务器
    m_pKernel->sendData((char*)&rq, sizeof(rq));
}

void Widget::on_pushButton_7_clicked()
{
    if (m_currentPage > 0) {
        m_currentPage--;
        STRU_GETFILELIST_RQ sgr;
        sgr.m_userId = m_userId;
        sgr.m_pageIndex = m_currentPage;
        sgr.m_pageSize = 15;  // 每页15个文件
        m_pKernel->sendData((char*)&sgr, sizeof(sgr));
    }
}

void Widget::on_pushButton_8_clicked()
{
    if (m_currentPage < m_totalPages - 1) {
        m_currentPage++;
        STRU_GETFILELIST_RQ sgr;
        sgr.m_userId = m_userId;
        sgr.m_pageIndex = m_currentPage;
        sgr.m_pageSize = 15;  // 每页15个文件
        m_pKernel->sendData((char*)&sgr, sizeof(sgr));
    }
}
void Widget::on_pushButton_9_clicked()
{
    int row = ui->tableWidget->currentRow();
    if (row < 0) {
        QMessageBox::warning(this, "上传控制", "请选择要操作的文件");
        return;
    }

    QTableWidgetItem *item = ui->tableWidget->item(row, 0);
    QString fileName = item->text();

    // 在文件列表中查找对应的上传任务
    STRU_FILE *pfile = nullptr;
    for (auto it : m_lstFileInfo) {
        if (0 == strcmp(it->m_szFileName, fileName.toStdString().c_str())) {
            pfile = it;
            break;
        }
    }

    if (!pfile) {
        QMessageBox::warning(this, "上传控制", "未找到对应的上传任务");
        return;
    }

    // 检查当前状态
    std::map<std::string, std::string> taskInfo;
    if (!RedisManager::instance().getUploadTask(m_userId, pfile->m_szFileMD5, taskInfo)) {
        QMessageBox::warning(this, "上传控制", "无法获取任务状态");
        return;
    }

    QString status = QString::fromStdString(taskInfo["status"]);

    if (status == "uploading") {
        // 暂停上传
        if (RedisManager::instance().pauseUploadTask(m_userId, pfile->m_szFileMD5)) {
            // 停止进度条动画
            m_targetProgress = pfile->m_pProgressBar->value();
            m_currentDisplayProgress = m_targetProgress;

            // 更新UI状态
            pfile->m_pProgressBar->setStyleSheet("QProgressBar::chunk { background-color: orange; }");
            pfile->m_pProgressBar->setFormat(QString("%1 - 已暂停 %p%").arg(pfile->m_szFileName));

            // 更新按钮文本为"继续"
            ui->pushButton_9->setText("继续上传");

            QMessageBox::information(this, "上传控制", "上传已暂停");
        } else {
            QMessageBox::warning(this, "上传控制", "暂停上传失败");
        }
    } else if (status == "paused") {
        // 继续上传
        // 发送续传请求
        STRU_UPLOADFILEINFO_RQ sur;
        sur.m_filesize = pfile->m_FileSize;
        strcpy(sur.m_szFileMD5, pfile->m_szFileMD5);
        strcpy(sur.m_szFileName, pfile->m_szFileName);
        strcpy(sur.m_szFileUploadTime, pfile->m_szFileuploadTime);
        sur.m_userId = m_userId;
        sur.m_filepos = pfile->m_pos;

        if (m_pKernel->sendData((char*)&sur, sizeof(sur))) {
            RedisManager::instance().resumeUploadTask(m_userId, pfile->m_szFileMD5);

            // 更新UI状态
            pfile->m_pProgressBar->setStyleSheet(""); // 恢复默认样式
            pfile->m_pProgressBar->setFormat(QString("%1 - 上传中 %p%").arg(pfile->m_szFileName));

            // 更新按钮文本为"暂停"
            ui->pushButton_9->setText("暂停上传");

            QMessageBox::information(this, "上传控制", "继续上传");
        } else {
            QMessageBox::warning(this, "上传控制", "继续上传失败");
        }
    }
}


